<!--
Google IO 2012 HTML5 Slide Template

Authors: Eric Bidelman <ebidel@gmail.com>
         Luke Mahé <lukem@google.com>

URL: https://code.google.com/p/io-2012-slides
-->
<!DOCTYPE html>
<html>
<head>
  <title>OAuth 2.0 for Identity and Data Access</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="chrome=1">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <link rel="stylesheet" media="all" href="theme/css/default.css">
  <link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="theme/css/phone.css">
  <base target="_blank"> <!-- This amazingness opens all links in a new tab. -->
  <script data-main="js/slides" src="js/require-1.0.8.min.js"></script>
  
  
  <script src="//apis.google.com/js/api.js"></script>
  <script src="//apis.google.com/js/client.js"></script>
  
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.20/jquery-ui.min.js"></script>
  
  <link type="text/css" href="theme/css/custom-theme/jquery-ui-1.8.20.custom.css" rel="stylesheet" />
  
  <script type="text/javascript">
    function checkAuthImmediate() {
      gapi.auth.authorize({
        client_id : '200854358599.apps.googleusercontent.com',
        scope : 'https://www.googleapis.com/auth/tasks'
      }, handleAuthResultImmediate);
    }
  
    function checkAuth() {
      gapi.auth.authorize({
        client_id : '200854358599.apps.googleusercontent.com',
        scope : 'https://www.googleapis.com/auth/tasks',
        approval_prompt: 'force'
      }, handleAuthResultPopup);
    }
  
    function loginCall() {
      gapi.auth.authorize({
        client_id : '63372841175.apps.googleusercontent.com',
        scope : 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile',
        approval_prompt: 'force'
      }, handleLoginResultPopup);
    }
  
    function init() {
      checkAuthImmediate();
    }
  
    function handleAuthResultImmediate() {
      if (gapi.auth.getToken()) {
        gapi.client.load('tasks', 'v1', makeRequest);
      }
    }
  
    function handleAuthResultPopup() {
      gapi.client.load('tasks', 'v1', makeRequest);
    }
  
    function handleLoginResultPopup() {
      gapi.client.load('oauth2', 'v2', makeUserInfoRequest);
    }
  
    function authAndCall() {
      checkAuth();
    }
  
    function loginAndCall() {
      loginCall();
    }
  
    function displayToken() {
      creds = gapi.auth.getToken();
      alert(creds.access_token);
    }
  
    function makeUserInfoRequest() {
      var request = gapi.client.oauth2.userinfo.get({});
      request.execute(function(response) {
          $("#signup-button").hide();
          $("#ar-token-tokeninfo").text(gapi.auth.getToken().access_token);
          $("#ar-token-userinfo").text(gapi.auth.getToken().access_token);
          $("#ar-unique-id").text(response.id);
          $("#ar-first").text(response.given_name);
          $("#ar-last").text(response.family_name);
          $("#ar-email").text(response.email);
          $("#ar-profile").html(
              '<img src="' + response.picture + '" style="vertical-align:text-top;" />');
        });
    }
  
    function makeRequest() {
      var request = gapi.client.tasks.tasks.list({
        "tasklist" : "@default"
      });
      request.execute(function(response) {
        var items = response['items'];
        for (task in items) {
          if (task < 4) {
            $("#accordion").append(
                "<div><h3><a href=\"#\">" + items[task].title + "</a></h3></div>");
          }
        }
        $("#accordion").accordion({
          header : "h3"
        });
        $("#accordion").show();
        $("#oauthActionButton").hide();
      });
    }
  </script>
  <script type="text/javascript">
    gapi.load('auth', init);
  </script>
  
  <style type="text/css">
    /*this is what we want the div to look like*/
    .blackout {
      background-color: #000000;
      z-index: 5000;
  
      /*set the div in the top-left corner of the screen*/
      position:absolute;
      top:0;
      left:0;
      
      /*set the width and height to 100% of the screen*/
      width:100%;
      height:100%;
   
      display: none;
    }
    
    #ar-profile img {
      height: 150px;
    }
  
    .displayBlock {
      display: block;
    }
  </style>
</head>
<body style="opacity: 0">
<div id="blackout" class="blackout"></div>
<slides class="layout-widescreen">

  <slide class="logoslide nobackground">
    <article class="flexbox vcenter">
      <span><img src="images/google_developers_logo.png"></span>
    </article>
  </slide>

  <slide class="title-slide segue nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <!-- The content of this hgroup is replaced programmatically through the slide_config.json. -->
    <hgroup class="auto-fadein">
      <h1 data-config-title><!-- populated from slide_config.json --></h1>
      <h2 data-config-subtitle><!-- populated from slide_config.json --></h2>
      <p data-config-presenter><!-- populated from slide_config.json --></p>
    </hgroup>
  </slide>

  <slide class="segue nobackground">
    <article class="flexbox vcenter auto-fadein">
      <center><p style="font-size: 100px;" class="blue">
        What does <br /> Google want?
      </p></center>
    </article>
  </slide>

  <slide>
    <article>
      <p style="font-size: 36px;">
        1) We want you online as much as possible<br /><br />
        2) We want you to use search<br /><br />
        3) We want to personalize your experience
      </p>
    </article>
  </slide>
  <slide>
    <article>
      <p style="font-size: 36px;">
        1) We want you online as much as possible<br /><br />
        2) We want you to use search<br /><br />
        3) We want to personalize your experience<br /><br />
      </p>
    </article>
    <hgroup>
      <h2>All these things require identity</h2><br/>
      <h2>Google is betting on OAuth 2.0 and OpenID Connect!</h2>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>OAuth 2.0 and OpenID Connect</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        1) OAuth 2.0 is a framework or toolset, not a protocol<br /><br />
        2) The core of OAuth 2.0 is finished and frozen<br /><br />
	3) OIDC is an interoperable protocol built on OAuth 2.0<br /><br />
	4) OIDC isn’t quite finished, but already works quite well.
      </p>
    </article>
  </slide>

  <slide class="fill nobackground" style="background-image: url(images/authentication.jpg)">
    <hgroup>
      <h2 class="black" style="font-size: 100px; font-family: courier; position:absolute; bottom:50px;">Authentication</h2>
    </hgroup>
  </slide>

  <slide class="fill nobackground" style="background-image: url(images/authorization.jpg)">
    <hgroup>
      <h2 class="black" style="font-size: 100px; font-family: courier; position:absolute; top:50px;">Authorization</h2>
    </hgroup>
  </slide>

  <slide class="segue dark quote nobackground">
    <aside class="gdbar right bottom"><img src="images/question_marks.png"></aside>
    <article class="flexbox vleft auto-fadein">
      <p style="font-size: 70px; line-height: 1.2;">
        Have you ever<br /><b>shared your password<br />with an app</b><br />so it could use your data?<br />&nbsp;
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Your opportunity</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        1) Eliminate the need for users to reveal their password to your app<br /><br />
        2) Restrict the level of data available to your app<br /><br />
        3) Allow users to revoke access to their data 
      </p>
    </article>
  </slide>

  <slide class="segue nobackground">
    <article class="flexbox vcenter auto-fadein">
      <center><p style="font-size: 100px;" class="blue">
        OAuth 2.0 <br /> for Authorization
      </p></center>
    </article>
  </slide>

  <slide class="segue dark quote nobackground">
    <aside class="gdbar right bottom"><img src="images/question_marks.png"></aside>
    <article class="flexbox vleft auto-fadein">
      <p style="font-size: 70px; line-height: 1.2;">
        Do you use the same<br /><b>username &amp; password</b><br />for multiple web sites?<br />&nbsp;
      </p>
    </article>
  </slide>

  <slide class="segue dark quote nobackground">
    <aside class="gdbar right bottom"><img src="images/question_marks.png"></aside>
    <article class="flexbox vleft auto-fadein">
      <p style="font-size: 65px; line-height: 1.2;">
        <b>How many keystrokes</b><br />do you type to<br /><b>sign up for a new account?</b><br />&nbsp;
      </p>
    </article>
  </slide>

  <slide class="segue dark quote nobackground">
    <article class="flexbox vcenter auto-fadein">
      <p style="font-size: 200px;">
        50+!
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Your opportunity</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        1) Minimize how many passwords users need<br /><br />
        2) Discourage password re-use<br /><br />
        3) Optimize sign-up flows to onboard users faster
      </p>
    </article>
  </slide>

  <slide class="segue nobackground">
    <article class="flexbox vcenter auto-fadein">
      <center><p style="font-size: 90px;" class="blue">
        OAuth 2.0 <br />for Login
      </p></center>
      <p style="font-size: 50px;" class="blue">
        (OpenID Connect)
      </p>
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>OAuth 2.0 for Authorization</h2>
    </hgroup>
  </slide>

  <slide class="segue dark quote nobackground">
    <article class="flexbox center vcenter auto-fadein">
      <p style="font-size: 100px;">
        Google: 35+ APIs!
      </p> 
      <p style="font-size: 50px; margin-top: 20px;">
        Many other OAuth providers...
      </p>
    </article>
  </slide>

  <slide class="segue dark quote nobackground">
    <article class="flexbox vcenter auto-fadein">
      <p style="font-size: 200px;">
        Goal
      </p>
    </article>
  </slide>

  <slide class="fill nobackground" style="background-image: url(images/istock_token_boston.jpg)">
  </slide>
  
  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>I have the token.  Now what?</h2>
      <h3>Calling the API</h3>
    </hgroup>
  </slide>
  
  <slide>
    <hgroup>
      <h2>But... how do I call the API?</h2>
      <h3>Using access tokens</h3>
    </hgroup>
    <article class="build">
<h3>Using a HTTP Header:</h3>
      <pre class="" data-lang="HTTP">GET /tasks/v1/lists/@default/tasks HTTP/1.1
Host: www.googleapis.com
<b>Authorization: Bearer 1/hGAFZKUio3NOc90BxjU48l</b></pre>
<h3>Using a Query Parameter:</h3>
      <pre class="" data-lang="HTTP">GET /tasks/v1/lists/@default/tasks<b>?access_token=1/hGAFZKUio3NOc90BxjU48l</b> HTTP/1.1
Host: www.googleapis.com</pre>
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>Getting Started</h2>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>APIs Console</h2>
      <h3>developers.google.com/console</h3>
    </hgroup>
    <article>
      <img src="images/apis_console.png" class="" height="400" style="margin-top: -10px;" />
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>Pure JavaScript Flow</h2>
      <h3>Developing Client-side Applications</h3>
    </hgroup>
  </slide>

  <slide class="fill">
    <article class="build">
      <img src="images/flow1-image1.png" width="350" style="position: absolute; left: 10px; top: 200px; " /><span>
      <img src="images/flow1-image2.png" width="250" style="position: absolute; left: 100px; top: 80px; " />
      <img src="images/flow1-image3.png" width="350" style="position: absolute; left: 375px; top: 10px;" /></span><span>
      <img src="images/flow1-image4.png" width="315" style="position: absolute; left: 725px; top: 50px;" />
      <img src="images/flow1-image5.png" width="350" style="position: absolute; right: 10px; top: 200px;" /></span><span>
      <img src="images/flow1-image6.png" width="300" style="position: absolute; right: 175px; bottom: 120px;" />
      <img src="images/flow1-image7.png" width="120" style="position: absolute; left: 500px; bottom: 50px;" /></span>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Google APIs Client Library for JavaScript</h3>
    </hgroup>
    <article>
   <button onClick="authAndCall()" id="oauthActionButton">Let's see it in action!</button>

                <div id="accordion" style="display: none">
My Google tasks:
                </div>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Google APIs Client Library for JavaScript</h3>
    </hgroup>
    <article class="build">
<pre class="prettyprint" data-lang="javascript">gapi.auth.authorize({
  client_id: '387636757294.apps.googleusercontent.com', 
  scope: 'https://www.googleapis.com/auth/tasks'},
  handleAuthResultPopup);

function handleAuthResultPopup() {
  alert(gapi.auth.getToken());
}
</pre>
    </article>
  </slide>


  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Step 1 - App directs the user to Google for Authorization</h3>
    </hgroup>
    <article>
      <pre class="prettyprint build" data-lang="javascript"><span>&lt;script type="text/javascript"&gt;
    var clientId = '387636757294.apps.googleusercontent.com';
    var authorizationEndpoint = 'https://accounts.google.com/o/oauth2/auth';</span><span>
    var redirectUri = 'https://taskmandemo.appspot.com/oauth2callback.html';</span><span>
    var scope = 'https://www.googleapis.com/auth/tasks';</span><span>

    function startOauth() {
      var url = authorizationEndpoint;
      url += '?response_type=token'
          +  '&amp;redirect_uri=' + encodeURIComponent(redirectUri)
          +  '&amp;client_id=' + encodeURIComponent(clientId)
          +  '&amp;scope=' + encodeURIComponent(scope);
      <b>var w = window.open(url, 'oauth', 'width=500,height=400');</b>
    }
&lt;/script&gt;</pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Step 1 - App directs the user to Google for Authorization</h3>
    </hgroup>
    <article>
      <pre class="" data-lang="url"><b>https://accounts.google.com/o/oauth2/auth</b>?
  client_id=387636757294.apps.googleusercontent.com&amp;
  scope=https://www.googleapis.com/auth/tasks&amp;
  redirect_uri=https://taskmandemo.appspot.com/oauth2callback.html&amp;
  response_type=token
</pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Step 2a - User authorizes access</h3>
    </hgroup>
    <article>
      <img src="images/manage_your_tasks.png" class="" />
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Step 2b - User is redirected back to the app</h3>
    </hgroup>
    <article>
      <pre class="build" data-lang="url"><span>https://taskmandemo.appspot.com/oauth2callback.html<b>#</b></span><span>
    access_token=ya29.AHES6ZT8XLGWjlrYfP1KvkLQVvYj81C6uA_bUsaZBKWB4ZE&amp;</span><span>
    token_type=Bearer&amp;</span><span>
    expires_in=3600</span></pre>
      <h3 class="build" style="font-size: 80px; font-weight: bold"><center>GOAL!</center></h3>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>Questions!</h3>
    </hgroup>
    <article><ul class="build" style="font-size: 30px">
        <li>How do I get the token back to the app from the popup window?</li>
        <li>How do I get another access token?</li>
        <li>What happens if the user isn't logged in?</li>
      </ul>
    </article>
  </slide>


  <slide>
    <hgroup>
      <h2>Client-side Flow in JavaScript</h2>
      <h3>When to use this Flow?</h3>
    </hgroup>
    <article>
      <ul class="build" style="font-size: 30px">
        <li>You're looking for simplicity</li>
        <li>You like coding in JavaScript</li>
        <li>You only need access when the user is logged into Google</li>
      </ul>
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>Server-side Flow in Java</h2>
    </hgroup>
  </slide>

  <slide class="fill">
    <article class="build">
      <img src="images/flow2-image1.png" width="350" style="position: absolute; left: 10px; top: 200px; " /><span>
      <img src="images/flow2-image2.png" width="250" style="position: absolute; left: 100px; top: 80px; " />
      <img src="images/flow2-image3.png" width="350" style="position: absolute; left: 375px; top: 10px;" /></span><span>
      <img src="images/flow2-image4.png" width="310" style="position: absolute; left: 725px; top: 45px;" />
      <img src="images/flow2-image5.png" width="350" style="position: absolute; right: 10px; top: 200px;" /></span><span>
      <img src="images/flow2-image6.png" width="350" style="position: absolute; right: 100px; bottom: 50px;" /></span><span>
      <img src="images/flow2-image7.png" height="110" style="position: absolute; right: 400px; bottom: 200px;" />
      <img src="images/flow2-image8.png" width="98" style="position: absolute; right: 500px; bottom: 200px;" /></span><span>
      <img src="images/flow2-image9a.png" width="150" style="position: absolute; left: 475px; bottom: 100px;" />
      <img src="images/flow2-image9.png" width="98" style="position: absolute; left: 350px; bottom: 50px;" /></span>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 1 - App re-directs the user</h3>
    </hgroup>
    <article>
      <pre class="prettyprint build" data-lang="java"><span>
// Instantiating some dependencies
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();</span><span>

// Building the flow and the redirect URL
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, SCOPES).build();

GoogleAuthorizationCodeRequestUrl urlBuilder =
        flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI);
</span><span>
// Redirecting users to the grant screen
<b>resp.sendRedirect(urlBuilder.build());</b></span>
      </pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 1 - App re-directs the user</h3>
    </hgroup>
    <article>
      <pre class="" data-lang="url">https://accounts.google.com/o/oauth2/auth?
  client_id=387636757294.apps.googleusercontent.com&amp;
  scope=https://www.googleapis.com/auth/tasks&amp;
  redirect_uri=https://taskmandemo.appspot.com/oauth2callback&amp;
  <b>response_type=code&amp;
  access_type=offline</b>
</pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 2a - User authorizes access</h3>
    </hgroup>
    <article>
      <img src="images/manage_your_tasks_offline.png" class="" />
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 2b - User is redirected back to the app</h3>
    </hgroup>
    <article>
      <pre class="" data-lang="url">https://taskmandemo.appspot.com/oauth2callback?
    <b>code=4/jHpY6Rslb32PWBiR9bU6wJ4GrMmF.EjOUBPzd</b></pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 3 - App exchanges authorization code for access token</h3>
    </hgroup>
    <article class="build">
      <pre class="prettyprint" data-lang="java">
// Reading the auth code value from the URL
String authorizationCode = req.getParameter("code");

// Exchanging the auth code for tokens
GoogleTokenResponse tokenResponse =
        flow.newTokenRequest(authorizationCode).setRedirectUri(REDIRECT_URI).execute();

String accessToken = tokenResponse.getAccessToken();
String refreshToken = tokenResponse.getRefreshToken();</pre>
      <h3 class="" style="font-size: 80px; font-weight: bold"><center>GOAL!</center></h3>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 3 - App exchanges authorization code for access token</h3>
    </hgroup>
    <article class="build">
      <pre class="" data-lang="HTTP REQUEST">POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com

client_id=387636757294.apps.googleusercontent.com&amp;
redirect_uri=https://taskmandemo.appspot.com/oauth2callback&amp;
<b>grant_type=authorization_code&amp;
code=4/jHpY6Rslb32PWBiR9bU6wJ4GrMmF.EjOUBPzd&amp;
client_secret=-8IwOyyundwNY6W0B</b></pre>
      <pre class="" data-lang="HTTP RESPONSE">{ 
  <b>"access_token":"1/fFAGRNJru1FTz70BzhT3Zg"</b>,
  <b>"refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" </b>
  "expires_in":3600,
  "token_type":"Bearer",
}</pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 4 - App exchanges refresh token for a new access token</h3>
    </hgroup>
    <article>
      <pre class="prettyprint" data-lang="java"><b>// nothing to see here!</b></pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Step 4 - App exchanges refresh token for a new access token</h3>
    </hgroup>
    <article class="build">
<pre class="" data-lang="HTTP REQUEST">POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded

client_id=387636757294.apps.googleusercontent.com&amp;
client_secret=-8IwOyyundwNY6W0B&amp;
<b>refresh_token=1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI&amp;
grant_type=refresh_token</b></pre>
      <pre class="" data-lang="HTTP RESPONSE">{ 
  <b>"access_token":"1/hGAFZKUio3NOc90BxjU48l"</b>,
  "expires_in":3600,
  "token_type":"Bearer"
}</pre>
    </article>
  </slide>


  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>Questions!</h3>
    </hgroup>
    <article><ul class="build" style="font-size: 30px">
        <li>When do refresh tokens expire?</li>
        <li>How do I store the refresh tokens?</li>
      </ul>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Server-side Flow in Java</h2>
      <h3>When to use this Flow?</h3>
    </hgroup>
    <article>
      <ul class="build" style="font-size: 30px">
        <li>You're looking for long-lived access to user data</li>
        <li>You need access when the user isn't at the keyboard</li>
        <li>You need to call the API from server-side code</li>
        <li>More secure</li>
      </ul>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Tell me more about scopes</h2>
      <h3>Getting authorization for multiple APIs at once</h3>
    </hgroup>
    <article>
<h3>Space-delimited list!</h3>
      <pre>https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/plus.me</pre>
    </article>
  </slide>
  
  
  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>App-based Authorization</h2>
    </hgroup>
  </slide>

  <slide class="fill">
    <article class="build">
      <img src="images/flow3-image1.png" width="135" style="position: absolute; right: 250px; top: 350px; " /><span>
      <img src="images/flow3-image2.png" height="200" style="position: absolute; right: 250px; top: 130px; " />
      <img src="images/flow3-image3.png" width="150" style="position: absolute; left: 450px; top: 60px;" /></span><span>
      <img src="images/flow3-image4.png" width="275" style="position: absolute; left: 420px; top: 400px;" />
      <img src="images/flow3-image5.png" width="150" style="position: absolute; left: 250px; top: 350px;" /></span>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>App-based Authorization</h2>
      <h3>Using service accounts</h3>
    </hgroup>
    <article><pre class="prettyprint build" data-lang="java"><span>/** Email of the Service Account */
private static final String SERVICE_ACCOUNT_EMAIL = "&lt;some-id&gt;@developer.gserviceaccount.com";

/** Path to the Service Account's Private Key file */
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "privatekey.p12";
</span><span>
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(httpTransport).setJsonFactory(jsonFactory)
    .setServiceAccountId(SERVICE_ACCOUNT_EMAIL).setServiceAccountScopes(SCOPES)
    .setServiceAccountPrivateKeyFromP12File(new File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
    .build();
String accessToken = credential.getAccessToken();</span></pre>
      <center><h3 class="build" style="font-size: 80px; font-weight: bold"><span>GOAL!</span></h3></center>

  </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>Tools</h2>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>OAuth 2.0 Playground</h2>
    </hgroup>
    <article class="flexbox vcenter" style="font-size: 30px">
      <img src="images/oauth_playground.png" height="500px" />
      <h3>code.google.com/oauthplayground</h3>
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>Mobile Authorization</h2>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>Three Techniques</h2>
    </hgroup>
    <article>
      <img src="images/mobile_webview.png" style="float: right" />
      <ul class="build" style="font-size: 30px">
        <li>Cross-platform - Embedded WebViews</li>
        <li>Cross-platform - System web browser</li>
        <li>Android-specific - GoogleAuthUtil</li>
      </ul>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>GoogleAuthUtil</h2>
    </hgroup>
    <article class="flexbox vcenter">
      <img src="images/android_gps.png" height="500" style="margin-top: -10px;" />
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>GoogleAuthUtil</h2>
      <h3>App Registration</h3>
    </hgroup>
    <article class="flexbox vcenter">
      <img src="images/create_client_id_android.png" />
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>GoogleAuthUtil</h2>
      <h3>Acquiring an access token</h3>
    </hgroup>
    <article class="flexbox vcenter">
      <img src="images/gau.png" />
      </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>OAuth 2.0 for Login</h2>
      <br/>
      <h3>A.k.a. OpenID Connect</h3>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>Authentication Goals</h2>
      <h3>Traditional signup form</h3>
    </hgroup>
    <article style="font-size: 30px">
      <img src="images/sign_up_form.png" height="450px" />
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Authentication Goals</h2>
      <h3>New signup form</h3>
    </hgroup>
    <article style="font-size: 30px">
    <script>
    $(function() {
		$( "button", ".signup-button" ).button();
	});
    </script>

    <div style="margin-left: 100px; background: #eee; padding: 20px;">
      <p style="line-height: 100%; color: black; font-family: Verdana, sans-serif;">
	Email (optional): <span id="ar-email">_______________________</span><br />
      </p>
      <div class="signup-button" >
	<button id="signup-button" onclick="loginAndCall()" style="font-size: 20px"><img src="https://www.google.com/favicon.ico" /> Sign up with Google</button>
      </div>
    </div>
    <p/>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Authentication Goals</h2>
    </hgroup>
    <article style="font-size: 30px">
      <ul >
        <li>Make it faster and easier to onboard users</li>
        <li>Securely get a unique, stable user identifier</li>
        <li>Personalize your site</li>
      </ul>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Authentication</h2>
      <h3>Step 1 - Use OAuth to get an access token</h3>
    </hgroup>
    <article style="font-size: 30px" >
      <table>
        <tr>
          <th>Scope</th><th>Description</th>
        </tr>
        <tr>
          <td>openid profile</td><td>Unique id, name, profile photo, profile URL, country, language, timezone, birthdate, etc.</td>
        </tr>
        <tr>
          <td>openid email</td><td>E-mail address</td>
        </tr>
      </table>

      <h3 style="margin-top: 10px">Request access:</h3>
      <pre class="" data-lang="url"><b>https://accounts.google.com/o/oauth2/auth</b>?
  <b>client_id</b>=387636757294.apps.googleusercontent.com&amp;
  <b>scope</b>=openid%20email%20profile&amp;
  <b>redirect_uri</b>=https://taskmandemo.appspot.com/oauth2callback-authn.html&amp;
  <b>response_type</b>=token </pre>
    </article>
  </slide>


 <slide>
    <hgroup>
      <h2>Authentication</h2>
      <h3>Step 1 - Use Google-provided button and library</h3>
    </hgroup>
    <article style="font-size: 30px">
      <img src="images/login_button.png" /><br /><br />
      <pre class="prettyprint" data-lang="javascript">&lt;script src="https://plus.google.com/js/plusone.js"&gt;&lt;/script&gt;
&lt;g:plus action="connect"
  clientid="387636757294.apps.googleusercontent.com"
  callback="handleAuthResult"&gt;
&lt;/g:plus&gt;</pre>
      <pre class="prettyprint" data-lang="javascript">function handleAuthResult() {
  alert(gapi.auth.getToken());
}</pre>

    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Authentication</h2>
      <h3>Step 2 - Use TokenInfo API to get a secure, unique user identifier</h3>
    </hgroup>
    <article style="font-size: 30px">
       My id: <span id="ar-unique-id"></span><br /><br />
<pre class="" data-lang="url">https://www.googleapis.com/oauth2/v2/tokeninfo?
  access_token=<span id="ar-token-tokeninfo"></span></pre>
<pre class="prettyprint" data-lang="json">{
 "issued_to": "387636757294.apps.googleusercontent.com",
 <b>"audience": "387636757294.apps.googleusercontent.com",</b>
 <b>"user_id": "107606703558161507946",</b>
 "scope": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
 "expires_in": 3574,
 "email": "tim.bray@gmail.com",
 "verified_email": true,
 "access_type": "online"
}</pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Personalization</h2>
      <h3>Use UserInfo API to get user profile data</h3>
    </hgroup>
    <article style="font-size: 30px">
<pre class="" data-lang="url">https://www.googleapis.com/oauth2/v2/userinfo?
  access_token=<span id="ar-token-userinfo"></span></pre>
<pre class="prettyprint build" data-lang="json"><span>{
 "id": "107606703558161507946",
 "email": "tim.bray@gmail.com",
 "verified_email": true,
 "name": "Tim Bray",
 "given_name": "Tim",
 "family_name": "Bray",
 "link": "https://plus.google.com/107606703558161507946",
 "picture": "https://lh4.googleusercontent.com/-RmVdD4RJbTQ/AAAAAAAAAAI/AAAAAAAABL0/VaR7uNMDImU/s250-c-k/photo.jpg",
 "gender": "male",
 "birthday": "0000-21-06",
 "locale": "en"
}</span></pre>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>OAuth 2.0 Login Demo</h2>
    </hgroup>
    <article class="flexbox vcenter" style="font-size: 30px">
      <img src="images/openid_connect_demo2.png" height="500px" />
      <h3>oauthssodemo.appspot.com</h3>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Hybrid Apps</h2>
    </hgroup>
    <article class="flexbox vcenter">
      <img width="900" src="images/Hybrid.png" />
      </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Hybrid Apps</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        1) Register a project at Developer Console<br /><br />
        2) Make a Client ID in it for a Web app<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 30px;">(Let’s say the Client ID is <code>“WebID29”</code>)</span><br/><br/>
        3) Make a Client ID in that project for an Android app<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 30px;">(Let’s say the Client ID is <code>“AndroidId31”</code>)</span><br/><br/>
	4) Get an OAuth2 ID Token<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 30px;">Android app calls <code>getToken</code> with <code>scope="audience:server:webId29"</code></span><br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 30px;">No prompt to user <span style="color:red;">if two Client IDs are in same project</span></span><br />
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Hybrid Apps</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        5) Send the token to the server (using https <span style="color: red">of course</span>) <br/><br/>
        6) Server validates the token using Google library<br/>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 30px;">Checks that <code>token.aud="WebId29"</code></span><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: 30px;">Checks that <code>token.cid="AndroidId31"</code></span><br/>
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>Hybrid Apps</h2>
      <h3>Given (1)-(6), your server can be reasonably confident that:</h3>
    </hgroup>
    <article>
      <p style="font-size: 36px; ">
        1) Google generated the token, and believes that<br/><br/>
        2) the person (<code>“uid”</code> field) is currently authenticated, and</br></br>
        3) is using the app in the <code>“cid”</code> field.
      </p>
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>AccountChooser for Login</h2>
      <br/>
      <h3>One click FTW!</h3>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
      <h3>Acquiring an access token</h3>
    </hgroup>
    <article class="flexbox vcenter">
      <img width="700" src="images/accountchooser.png" />
      </article>
  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <p>&nbsp;<br/></p>
      <pre style="font-size: 36px; line-height: 100%;" class="prettyprint" data-lang="javascript">&lt;script 
    type="text/javascript"        
    src="https://www.accountchooser.com/ac.js">
  // options go here
  &lt;/script>
</pre>  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        1) <b>ac.js</b> redirects landing page to accountchooser.com<br/>
	&nbsp;&nbsp;&nbsp;&nbsp;(send along a list of IDPs you like)
      </p>
    </article>
      <pre class="prettyprint" data-lang="javascript">&lt;script 
    type="text/javascript"
    src="https://www.accountchooser.com/ac.js">
    providerIds: [
      "facebook.com", "aol.com", "google.com"
    ]
  &lt;/script>
</pre>  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px; ">
        2) <b>ac.js</b> POSTs to your account-status<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- email address<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- IDP (from your list, if provided)<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- Photo URL (if AccountChooser has it)<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- Display-name (if AccountChooser has it)
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px; ">
        3) Your account-status returns JSON:<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- <code>{"registered":true}</code> sends them to the login page<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- <code>{"registered":false}</code> sends them to the signin page<br/><br/>
	&nbsp;&nbsp;&nbsp;&nbsp;- <code>{"authUrl":"</code>&lt;url><code>"}</code> sends them to an IDP
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        4) After signin, update <b>ac.js</b>
      </p>
    </article>
      <pre class="prettyprint" data-lang="javascript">&lt;script 
    type="text/javascript"
    src="https://www.accountchooser.com/ac.js">
    storeAccount: {
      "email":       ...
      "providerId":  ...
      "photoUrl":    ...
      "displayName": ...
  }  &lt;/script>
</pre>  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px;">
        5) There is no Step 5!
      </p>
    </article>
  </slide>

  <slide>
    <hgroup>
      <h2>AccountChooser</h2>
    </hgroup>
    <article>
      <p style="font-size: 36px; ">
        1) <b>ac.js</b> redirects landing page to accountchooser.com,<br/><br/>
        2) <b>ac.js</b> POSTs to your account-status,<br/><br/>
        3) Your account-status returns JSON,<br/><br/>
	4) After signin, update <b>ac.js</b>
      </p>
      <h3 class="build" style="font-size: 80px; font-weight: bold"><center>GOAL!</center></h3>
    </article>
  </slide>

  <slide class="segue dark nobackground">
    <aside class="gdbar"><img src="images/google_developers_icon_128.png"></aside>
    <hgroup class="auto-fadein">
      <h2>Summary</h2>
    </hgroup>
  </slide>

  <slide>
    <hgroup>
      <h2>Resources</h2>
    </hgroup>
    <article style="font-size: 30px">
      <ul>
        <li>These slides - <a href="https://oauth2-preso.appspot.com">oauth2-preso.appspot.com</a></li>
        <li>APIs Console - <a href="https://developers.google.com/console">developers.google.com/console</a></li>
        <li>JavaScript library - <a href="https://code.google.com/p/google-api-javascript-client/">code.google.com/p/google-api-javascript-client</a></li>
        <li>Python library - <a href="https://code.google.com/p/google-api-python-client/">code.google.com/p/google-api-python-client</a></li>
        <li>OAuth 2.0 Playground - <a href="https://code.google.com/oauthplayground">code.google.com/oauthplayground</a></li>
        <li>OAuth 2.0 Login Demo - <a href="https://oauthssodemo.appspot.com">oauthssodemo.appspot.com</a></li>
        <li>Google Play Services - <a href="https://developers.google.com/android/google-play-services/">developers.google.com/android/google-play-services</a></li>
      </ul>
    </article>
  </slide>

  <slide class="thank-you-slide segue nobackground">
    <aside class="gdbar right"><img src="images/google_developers_icon_128.png"></aside>
    <article class="flexbox vleft auto-fadein">
      <h2>&lt;Thank You!&gt;</h2>
    </article>
    <p class="auto-fadein" data-config-contact>
      <!-- populated from slide_config.json -->
    </p>
  </slide>

  <slide class="logoslide dark nobackground">
    <article class="flexbox vcenter">
      <span><img src="images/google_developers_logo_white.png"></span>
    </article>
  </slide>

  <slide class="backdrop"></slide>

</slides>

<!--[if IE]>
  <script src="https://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
  <script>CFInstall.check({mode: 'overlay'});</script>
<![endif]-->
</body>
</html>
